﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;
using TD.bom;

namespace TD.Renderer.Default
{
    public class Renderer : IRenderer
    {
        /// <summary>
        /// Canvas où seront disposés les éléments
        /// </summary>
        protected Canvas m_canvas;

        /// <summary>
        /// Constructeur
        /// </summary>
        /// <param name="p_canvas">Canvas où seront disposés les éléments</param>
        public Renderer(Canvas p_canvas)
        {
            m_canvas = p_canvas;
        }

        /// <summary>
        /// Effectue ou met à jour le rendu
        /// </summary>
        public void DoRendering()
        {
            Map l_map = Game.Instance.Map;

            // On met à jour la position des cases (utile ?)
            foreach (Case l_case in l_map.Cases)
            {
                if (l_case.RendererData != null)
                {
                    MoveElement((UIElement)l_case.RendererData, l_case.Position.X, l_case.Position.Y);
                }
            }

            // On met à jour la position des monstres
            foreach (Monster l_monster in l_map.CurrentWave.Monsters)
            {
                if (l_monster.RendererData != null)
                {
                    MoveElement((UIElement)l_monster.RendererData, l_monster.Position.X, l_monster.Position.Y);
                }
            }

            // S'il y a un point de passage sur la case, on le fait apparaître
            SolidColorBrush l_wayPointBrush = new SolidColorBrush(Color.FromArgb(255, 255, 255, 255));
            foreach (WayPoint l_wayPoint in l_map.WayPoints)
            {
                if (l_wayPoint.Case.RendererData != null)
                {
                    ((Rectangle)l_wayPoint.Case.RendererData).Stroke = l_wayPointBrush;
                }
            }

        }

        /// <summary>
        /// Gère l'ajout d'un objet de la carte à afficher
        /// </summary>
        /// <param name="p_mapObject">Objet de la carte ajouté</param>
        public void AddObject(MapObject p_mapObject)
        {
            Rectangle l_boundingRect = new Rectangle();
            l_boundingRect.Width = p_mapObject.Size.Width;
            l_boundingRect.Height = p_mapObject.Size.Height;

            if (p_mapObject is Case)
            {
                if (p_mapObject.TemplateName.StartsWith("case/1"))
                {
                    l_boundingRect.Fill = new SolidColorBrush(Color.FromArgb(255, 255, 220, 0));
                }
                else
                {
                    l_boundingRect.Fill = new SolidColorBrush(Color.FromArgb(255, 0, 240, 0));
                }
                l_boundingRect.Stroke = new SolidColorBrush(Color.FromArgb(255, 0, 0, 255));
            }
            else if (p_mapObject is Tower)
            {
            }
            else if (p_mapObject is Monster)
            {
                l_boundingRect.Stroke = new SolidColorBrush(Color.FromArgb(255, 255, 0, 0));
                l_boundingRect.Fill = new SolidColorBrush(Color.FromArgb(128, 255, 0, 0));
            }
            else if (p_mapObject is Projectile)
            {
            }

            p_mapObject.RendererData = l_boundingRect;
            m_canvas.Children.Add(l_boundingRect);
        }

        /// <summary>
        /// Gère la suppression d'un objet de la carte à afficher
        /// </summary>
        /// <param name="p_mapObject">Objet de la carte supprimé</param>
        public void RemoveObject(MapObject p_mapObject)
        {
            // Est-ce que cet objet était rendu ?
            if (p_mapObject.RendererData != null)
            {
                // Oui, il faut supprimer son rendu du jeu
                m_canvas.Children.Remove((UIElement)p_mapObject.RendererData);
                p_mapObject.RendererData = null;
            }
        }

        /// <summary>
        /// Déplace un élément sur l'écran
        /// </summary>
        /// <param name="p_element">élément à déplacer</param>
        /// <param name="x">nouvelle position x</param>
        /// <param name="y">nouvelle position y</param>
        public void MoveElement(UIElement p_element, double x, double y)
        {
            // Intégrité des paramètres
            if (p_element == null || !m_canvas.Children.Contains(p_element))
            {
                return;
            }

            p_element.SetValue(Canvas.LeftProperty, x);
            p_element.SetValue(Canvas.TopProperty, y);
        }
    }
}
